import { getCurrentInstance, inject, onBeforeUnmount, onBeforeMount } from 'vue'
import type { Node, Graph, Edge } from '@antv/x6'

function initData(source: Record<string, unknown>, target: Record<string, unknown>) {
  for (const [key, value] of Object.entries(source)) {
    if (key === 'type') continue
    if (key.indexOf('output') > -1) continue

    target[key] = value
  }
}

export function useNode() {
  const vm = getCurrentInstance()?.proxy
  const getNode = inject('getNode') as () => Node
  const getGraph = inject('getGraph') as () => Graph
  const node = getNode()
  const graph = getGraph()

  const changeData = function (e: GtGraphic.ChangeDataEvent) {
    console.group('changeData')
    console.log('e', e)
    console.log('cellId', e.cell.id)
    console.log('shape', e.cell.shape)
    console.log('data', e.current)
    console.log('vmData', vm!.$data)
    console.groupEnd()
    initData(e.current, vm!.$data!)
  }

  const change = function (value: unknown, port: string) {
    const currentEdges = graph.getEdges().filter(function (edge) {
      return (edge.source as Edge.TerminalCellLooseData).cell === node.id
    })

    if (currentEdges.length) {
      currentEdges.forEach(function (edge) {
        const targetNode = graph.getCellById((edge.target as Edge.TerminalCellLooseData).cell as string) as Node
        const targetPort = targetNode.getPort((edge.target as Edge.TerminalCellLooseData).port!)!

        console.group('currentEdges')
        console.log('inputPort', port)
        console.log('targetPort', targetPort)
        console.log('targetNode', targetNode)
        console.groupEnd()

        const data = (function () {
          const result = Object.create(null)
          result[node.id] = { id: node.id, value }
          return result
        })()

        targetNode.setData({ [targetPort.key]: data })
      })
      return
    }

    const data = (function () {
      const result = Object.create(null)
      result[node.id] = { id: node.id, value }
      return result
    })()

    node.setData({ [port]: data })
  }

  onBeforeMount(function () {
    initData(node.data, vm!.$data!)
  })

  node.on('change:data', changeData)
  onBeforeUnmount(function () {
    node.off('changeData', changeData)
  })

  return { node, graph, change }
}
